<template>
  <view :class="classNames" @click="handleChange">
    <template v-if="$slots.checkbox">
      <slot name="checkbox" :checked="computedChecked"></slot>
    </template>
    <template v-else>
      <view class="arco-icon-hover arco-checkbox-icon-hover">
        <view class="arco-checkbox-icon">
          <aIcon
            v-if="computedChecked"
            class="arco-checkbox-icon-inner"
            color="#FFFFFF"
            name="gouxuankuang-xuanzhong"
          ></aIcon>
        </view>
      </view>
      <view class="arco-checkbox-label">
        <slot name="default"></slot>
      </view>
    </template>
  </view>
</template>

<script lang="ts">
import { useFormItem } from "@/ArcoUni/hook/use-form-item";
import { isArray, isNull, isUndefined } from "@/utils/is";
import { computed, defineComponent, inject, ref, toRefs, watch } from "vue";
import context from "../arco-checkbox-group/content";
import aIcon from "../arco-icon/index.vue";
const Checkbox = defineComponent({
  name: "Checkbox",
  options: {
    // 虚拟化节点
    virtualHost: true,
  },
  components: {
    aIcon,
  },
  props: {
    modelValue: {
      type: [Boolean, Array],
      default: void 0,
    },
    defaultChecked: {
      type: Boolean,
      default: false,
    },
    value: {
      type: [String, Number, Boolean],
      default: void 0,
    },
    disabled: {
      type: Boolean,
      default: false,
    },
    indeterminate: {
      type: Boolean,
      default: false,
    },
    uninjectGroupContext: {
      type: Boolean,
      default: false,
    },
  },
  emits: ["update:modelValue", "change"],
  setup(props, { emit }) {
    const { disabled, modelValue } = toRefs(props);
    const prefixCls = "arco-checkbox";
    const checkboxGroupCtx = !props.uninjectGroupContext
      ? inject(context.checkboxGroupKey, void 0)
      : void 0;
    // 是否单选框组
    const isGroup = computed(
      () =>
        (checkboxGroupCtx == null ? void 0 : checkboxGroupCtx.name) ===
        "ArcoCheckboxGroup",
    );
    //
    const { mergedDisabled: _mergedDisabled, eventHandlers } = useFormItem({
      disabled,
    });

    const _checked = ref(props.defaultChecked);
    const computedValue = computed(() => {
      var _a;
      return isGroup.value
        ? checkboxGroupCtx == null
          ? void 0
          : checkboxGroupCtx.computedValue
        : (_a = props.modelValue) != null
          ? _a
          : _checked.value;
    });
    const computedChecked = computed(() => {
      var _a;
      return isArray(computedValue.value)
        ? computedValue.value.includes((_a = props.value) != null ? _a : true)
        : computedValue.value;
    });
    const mergedDisabled = computed(
      () =>
        (checkboxGroupCtx == null ? void 0 : checkboxGroupCtx.disabled) ||
        (_mergedDisabled == null ? void 0 : _mergedDisabled.value) ||
        (!computedChecked.value &&
          (checkboxGroupCtx == null ? void 0 : checkboxGroupCtx.isMaxed)),
    );

    const handleChange = (e) => {
      var _a, _b, _c, _d;
      if (mergedDisabled.value) {
        return;
      }
      const checked = !computedChecked.value;
      let newValue: any = checked;
      if (isArray(computedValue.value)) {
        const set = new Set(computedValue.value);
        if (checked) {
          set.add((_a = props.value) != null ? _a : true);
        } else {
          set.delete((_b = props.value) != null ? _b : true);
        }
        newValue = Array.from(set);
      }
      _checked.value = newValue;
      if (isGroup.value && isArray(newValue)) {
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        checkboxGroupCtx == null
          ? void 0
          : checkboxGroupCtx.handleChange(newValue, e);
      } else {
        emit("update:modelValue", newValue);
        emit("change", newValue, e);
        // eslint-disable-next-line @typescript-eslint/no-unused-expressions
        (_d = (_c = eventHandlers.value) == null ? void 0 : _c.onChange) == null
          ? void 0
          : _d.call(_c, e);
      }
    };

    const classNames = computed(() => {
      return [
        prefixCls,
        {
          [`${prefixCls}-checked`]: computedChecked.value,
          [`${prefixCls}-indeterminate`]: props.indeterminate,
          [`${prefixCls}-disabled`]: mergedDisabled.value,
        },
      ];
    });

    watch(modelValue, (value) => {
      if (isUndefined(value) || isNull(value)) {
        _checked.value = false;
      }
    });

    watch(computedValue, (value) => {
      var _a;
      let checked;
      if (isArray(value)) {
        checked = value.includes((_a = props.value) != null ? _a : true);
      } else {
        checked = value;
      }
      if (_checked.value !== checked) {
        _checked.value = checked;
      }
    });

    return {
      prefixCls,
      classNames,
      mergedDisabled,
      computedChecked,
      handleChange,
    };
  },
});
export default Checkbox;
</script>
